# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##--------------------------------------------------------------------------##
__docformat__ = "restructuredtext en"


from .. import gamelib as game
from .. import hint
from .. import pilelib as stack
from ..forms import klondike as KlondikeLayout
from ..gamelib import info as gi, game
from ..packlib import place
from ..piles import (talon as TalonStack, foundation as FoundationStack,)
from ..utillib.misc import kwdefault

Wrap = stack.StackWrapper
GT, SL = gi.GT, gi.SL


class Carthage(game.Game):
    """
    Finish 2 deck on _foundation_ using 8 Rowstack built down and 6 Reserve,
    dealing all Reserve except last on RowStack.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.klondike.KlondikeLayout
        - row [8 horz S foundations, vert offset]
        - talon [1 NW, no offset]
        - foundation [8 horz NE, no offset]
        - reserve [6 horz S, no offset]

      _talon_ : pysollib.stack.Stack
        .. pysollib.stacks.talon.Carthage_Talon (num_deal=2)
        Deal 2 card per reserve. Last deal 1 card per row. No
        redeals.

      _foundation_ : pysollib.stack.Stack
        .. pysollib.stack.SS_Foundation
        Build up in rank by same suit. Play top. Base ACE.

      _row_ : pysollib.stack.Stack
        .. pysollib.stack.SS_RowStack (max_move=1, max_accept=1)
        Init 1 card per. Build down in rank by same suit. Play top.

      _reserve_ : pysollib.stack.Stack
        .. pysollib.stack.OpenStack
        Init 6 card. Build none. Play top.

      _hint_ : pysollib.hint.AbstractHint
        .. pysollib.hint.CautiousDefaultHint
    """
    __info__ = dict(id=0x41ff1, name='Carthage', game_type=GT.RAGLAN, decks=2,
                    skill_level=SL.MOSTLY_SKILL, version='0.80fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = KlondikeLayout.KlondikeLayout
    _talon_ = Wrap(TalonStack.Carthage_Talon, num_deal=2)
    _foundation_ = stack.SS_Foundation
    _row_ = Wrap(stack.SS_RowStack, max_move=1, max_accept=1)
    _reserve_ = stack.OpenStack
    _hint_ = hint.CautiousDefaultHint

    def _create_game(self, **kw):
        """
        _create_game([rows=8, playcards=12, reserves=6]) -> Layout

        :returns: current layout with piles and their texts set.

        :seealso:
          `pysollib.layouts.klondike` for keyword definitions.
        """
        kwdefault(kw, rows=8, playcards=12, reserves=6)
        return super(Carthage, self)._create_game(**kw)

    def _start(self, rows=1, reserves=6, **kw):
        """
        _start([rows=1, reserves=6]) -> None

        Deal 1 card per row. Deal 6 card per reserve.
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(frames=0)
        self.s['talon'].dealRow()
        for i in range(reserves - 1):
            self.s['talon'].dealRow(rows=self.s['reserves'], frames=0)
        self._play_sound('deal')
        self.s['talon'].dealRow(rows=self.s.reserves)


class AlgerianPatience(Carthage):
    """
    Finish 2 deck on foundation using 8 tableau built either wrap and 6
    reserve, dealing per Reserve except last per RowStack.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.klondike.KlondikeLayout
        - row [8 horz S foundations, vert offset]
        - talon [1 NW, no offset]
        - foundation [8 horz NE, no offset]
        - reserve [6 S, no offset]

      _talon_ : pysollib.stack.Stack
        .. pysollib.stacks.talon.Carthage_Talon (num_deal=2)
        Deal 2 card per reserve. Last deal 1 card per row. No
        redeals

      _foundation_ : pysollib.stack.Stack
        .. pysollib.stacks.foundation.AceKingSS_Foundation
        Build in rank by same suit. Play top.
          - E 4. Build up. Base ace.
          - W 4. Init king. Build down. Base king.

      _row_ : pysollib.stack.Stack
        .. pysollib.stack.UD_SS_RowStack (mod=13)
        Init 1 card per. Build either in rank by same suit wrap. Play top.

      _reserve_ : pysollib.stack.Stack
        .. pysollib.stack.OpenStack
        Init 6 card. Build none. Play top.

      _hint_ : pysollib.hint.AbstractHint
        .. pysollib.hint.CautiousDefaultHint
    """
    __info__ = dict(id=0x41ff2, name='Algerian Patience', game_type=GT.RAGLAN,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='0.80fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _foundation_ = FoundationStack.AceKingSS_Foundation
    _row_ = Wrap(stack.UD_SS_RowStack, mod=13)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return KING of suit on top by suit for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.OneKing)

    def _start(self, **kw):
        """
        _start([rows=1, reserves=6]) -> None

        Deal king per E 4 foundation. Deal 1 card per row. Deal 6
        card per reserve.
        """
        self.s['talon'].dealRow(rows=self.s['foundations'][4:], frames=0)
        super(AlgerianPatience, self)._start(**kw)


class AlgerianPatience3(Carthage):
    """
    Finish 3 deck on _foundation_ using 8 Rowstack built either wrap and 8
    Reserve, dealing all Reserve except last on RowStack.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.klondike.KlondikeLayout
        - row [8 horz S foundations, vert offset]
        - talon [1 NW, no offset]
        - foundation [8 horz NE, no offset]
        - reserve [8 horz S, no offset]

      _talon_ : pysollib.stack.Stack
        .. pysollib.talons.Carthage_Talon (num_deal=2)
        Deal 2 card per `s.reserves`. Last deal 1 card per `s.rows`. No
        redeals

      _foundation_ : pysollib.stack.Stack
        .. pysollib.stack.SS_Foundation
        Init `ACE`. Build up in rank by same suit. Play top. Base `ACE`.

      _row_ : pysollib.stack.Stack
        .. pysollib.stack.UD_SS_RowStack (mod=13)
        Init 1 card per. Build either in rank by same suit wrap. Play top.

      _reserve_ : pysollib.stack.Stack
        .. pysollib.stack.OpenStack
        Init 6 card. Build none. Play top.

      _hint_ : pysollib.hint.AbstractHint
        .. pysollib.hint.CautiousDefaultHint
    """
    __info__ = dict(id=0x42079, name='Algerian Patience (3 decks)',
                    game_type=(GT.RAGLAN | GT.ORIGINAL), decks=3,
                    skill_level=SL.MOSTLY_SKILL, version='0.80fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = Wrap(stack.UD_SS_RowStack, mod=13)

    def _create_game(self, **kw):
        """
        _create_game([rows=8, playcards=12, reserves=8]) -> Layout

        :returns: current layout with piles and their texts set.

        :seealso:
          `pysollib.layouts.klondike` for keyword definitions.
        """
        kwdefault(kw, playcards=20, reserves=8)
        return super(AlgerianPatience3, self)._create_game(**kw)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on top by suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllAce)

    def _start(self):
        """
        _start([rows=1, reserves=6]) -> None

        Deal ace per foundation. Deal 1 card per row. Deal 6
        card per reserve.
        """
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        super(AlgerianPatience3, self)._start()


PROVIDES = [Carthage, AlgerianPatience, AlgerianPatience3]